<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>simply-lazy</title>
<style>
* {margin: 0; padding: 0;}

.repo-link {
  position: absolute;
  top: 0;
  right: 0;
  padding: 10px 10px 20px 20px;
  background: #fafafa;
  border-radius: 0 0 0 80%;
  transition: all 0.2s;
}
.repo-link:hover {
  background: #f7f7f7;
}

.demo {
  display: flex;
  flex-direction: row;
  font: 14px/1.5 consolas, monospace;
  border-radius: 5px;
  color: #333;
  border-bottom: 1px solid #d5d5d5;
}
.demo:last-child {
  border-bottom: none;
}
.demo .code,
.demo .output,
.demo .count {
  width: 40%;
  padding: 20px 30px;
  box-sizing: border-box;
}
.demo .count {
  width: 20%;
}

.demo .code {
  overflow: auto;
}
.demo pre,
.demo code {
  font: inherit;
}
.demo .code:before,
.demo .output:before,
.demo .count:before {
  display: block;
  color: #999;
}
.demo .code:before {
  content: '// code:';
}
.demo .output:before {
  content: '// output:';
}
.demo .count:before {
  content: '// count:';
}
</style>
</head>
<body>

<a href="https://github.com/luobotang/simply-lazy" class="repo-link">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
</a>

<script src="index.js"></script>
<script>
var demos = [(Lazy, print) => {
Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .map(i => i * 2)
  .each(i => print(i))
}, (Lazy, print) => {
Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .map(i => i * 2)
  .filter(i => i <= 10)
  .each(i => print(i))
}, (Lazy, print) => {
Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .map(i => i * 2)
  .filter(i => i <= 10)
  .take(3)
  .each(i => print(i))
}, (Lazy, print) => {
Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .filter(i => i <= 5)
  .each(i => print(i))
}, (Lazy, print) => {
Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .filter(i => i <= 5)
  .map(i => i * 2)
  .each(i => print(i))
}, (Lazy, print) => {
Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .filter(i => i <= 5)
  .map(i => i * 2)
  .take(3)
  .each(i => print(i))
}]

function renderDemo(demoFn) {
  var el = document.createElement('div')
  el.classList.add('demo')

  var count = {map: 0, filter: 0}
  var _lazy = list => proxySeq(Lazy(list))

  var output = []
  var print = msg => output.push(msg)
  demoFn(_lazy, print)

  function proxySeq(seq) {
    var handler = {
      get(target, name) {
        // captur method `map` and `filter`
        if (name === 'map' || name === 'filter') {
          // replace method with function that returns another proxy seq
          return fn => {
            // replace callback fn to count fn's call
            var _fn = (v, i) => {
              count[name]++
              return fn(v, i)
            }
            return proxySeq(target[name](_fn))
          }
        } else {
          return target[name]
        }
      }
    }
    return new Proxy(seq, handler)
  }

  el.innerHTML = (
    '<div class="code">' +
      '<pre>' +
        '<code>' +
          demoFn.toString().replace('(Lazy, print) => {\n', '').replace(/\n}$/, '') +
        '</code>' +
      '</pre>' +
    '</div>' +
    '<div class="output">' +
      output.join('<br>') +
    '</div>' +
    '<div class="count">' +
      'map: ' + count.map + '<br>' +
      'filter: ' + count.filter +
    '</div>'
  )

  document.body.appendChild(el)
}

demos.forEach(renderDemo)
</script>
</body>
</html>